package com.polaris.live.common.network.interceptor

import com.blankj.utilcode.util.GsonUtils
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.polaris.live.common.cacha.CacheUtil
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.constant.CommonConst
import com.polaris.live.common.resp.AppVersionVo
import com.polaris.live.common.util.UserAccountUtils
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody

/**
 * 响应体拦截器
 *
 * @author Created by 半仙 on 2023/9/23/023 18:01
 */
class ResponseInterceptor : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()
        val response = chain.proceed(originalRequest)

        if (response.isSuccessful) {
            val responseBody = response.body?.string()

            val responseBack = JsonParser.parseString(responseBody)
            if (responseBack is JsonObject) {
                val timestampElement = responseBack.get("timestamp")
                if (timestampElement.isJsonPrimitive) {
                    CacheUtil.setLastServerTime(timestampElement.asNumber.toLong())
                }

                val extElement = responseBack.get("ext")
                UserAccountUtils.handleExtAccount(extElement,timestampElement.asNumber.toLong())

                val codeElement = responseBack.get("code")
                if (codeElement.isJsonPrimitive) {
                    val code = codeElement.asInt
                    if (code == 501) {
                        authFailure(originalRequest, extElement)
                    } else if (code == CommonConst.ErrorCode.APP_FORCE_UPGRADE) {
                        appForceUpgrade(extElement)
                    }
                }
            }

            // 构建新的 Response 对象，重用之前读取的响应体
            return response.newBuilder()
                .body(responseBody?.toResponseBody(response.body?.contentType()))
                .build()
        }

        return response
    }

    private fun authFailure(originalRequest: Request, extElement: JsonElement?) {
        val token = UserManager.getUser().token
        val requestToken = originalRequest.headers["token"]
        if (token.isNullOrBlank() || requestToken.isNullOrBlank() || token == requestToken) {
            val failToken = if (extElement is JsonObject) {
                val failTokenElement = extElement.get("failToken")
                failTokenElement != null && failTokenElement.isJsonPrimitive && failTokenElement.asString == "1"
            } else {
                false
            }

            UserManager.onLogoutTrigger?.onLogout(
                UserManager.getUserId(), if (failToken) {
                    1000
                } else {
                    0
                }
            )
        }
    }

    private fun appForceUpgrade(extElement: JsonElement) {
        if (extElement !is JsonObject) {
            return
        }

        val appVersionElement = extElement.get("appVersion")
        if (appVersionElement !is JsonObject) {
            return
        }

        try {
            val vo = GsonUtils.getGson().fromJson(appVersionElement, AppVersionVo::class.java)
            if (vo != null) {
                UserManager.onAppForceUpgrade?.onAppForceUpgrade(vo)
            }
        } catch (_: Throwable) {
        }
    }
}